﻿using UnityEngine;
//using System.Collections;

/// <summary>
/// 自定义的int Vector2，它的哈希值的访问效率已经到达极限，
/// 但是坐标最大值是
/// x : +- 32767
/// y : +- 65535
/// </summary>
[System.Serializable]
public struct Vector2Int
{
    public int x;

    public int y;

    public int key;

    public Vector2Int(float a_x, float a_y)
    {
        this.x = (int)a_x;
        this.y = (int)a_y;
        key = (this.x) + (this.y << 0x0F);
    }

    public Vector2Int(int x, int y)
    {
        this.x = x;
        this.y = y;
        key = (this.x) + (this.y << 0x0F);
    }

    public override string ToString()
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("(");
        sb.Append(this.x);
        sb.Append(",");
        sb.Append(this.y);
        sb.Append(")");
        return sb.ToString();
    }

    public override bool Equals(object b)
    {
        if (b is Vector2Int)
        {
            var v = (Vector2Int)b;
            return this.x == v.x && this.y == v.y;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return key;
    }
    
    /// <summary>
    /// 使用key的数据
    /// </summary>
    /// <param name="a_Key">Vector2Int 的 HashCode</param>
    /// <returns></returns>
    public static Vector2Int ToVoxel2D(int a_Key)
    {
        int var_y = a_Key >> 0x0F;
        int var_x = a_Key & 0x7FFF;
        return new Vector2Int(var_x, var_y);
    }

    public static Vector2Int operator +(Vector2Int a, Vector2Int b)
    {
        return new Vector2Int(a.x + b.x, a.y + b.y);
    }
    public static Vector2Int operator -(Vector2Int a, Vector2Int b)
    {
        return new Vector2Int(a.x - b.x, a.y - b.y);
    }
    public static Vector2Int operator *(Vector2Int a, int b)
    {
        return new Vector2Int(a.x * b, a.y * b);
    }
    public static Vector2Int operator *(int b, Vector2Int a)
    {
        return new Vector2Int(a.x * b, a.y * b);
    }
    public static Vector2Int operator /(Vector2Int a, int b)
    {
        return new Vector2Int(a.x / b, a.y / b);
    }
    public static bool operator ==(Vector2Int lhs, Vector2Int rhs)
    {
        return lhs.x == rhs.x && lhs.y == rhs.y;
    }
    public static bool operator !=(Vector2Int lhs, Vector2Int rhs)
    {
        return lhs.x != rhs.x || lhs.y != rhs.y;
    }


    public static Vector2Int operator >>(Vector2Int a, int b)
    {
        return new Vector2Int(a.x >> b, a.y >> b);
    }
    public static Vector2Int operator <<(Vector2Int a, int b)
    {
        return new Vector2Int(a.x << b, a.y << b);
    }
    public static Vector2Int operator |(int b, Vector2Int a)
    {
        return new Vector2Int(a.x | b, a.y | b);
    }
    public static Vector2Int operator |(Vector2Int a, int b)
    {
        return new Vector2Int(a.x | b, a.y | b);
    }
    public static Vector2Int operator &(int b, Vector2Int a)
    {
        return new Vector2Int(a.x & b, a.y & b);
    }
    public static Vector2Int operator &(Vector2Int a, int b)
    {
        return new Vector2Int(a.x & b, a.y & b);
    }


    public static bool operator <(int l, Vector2Int r)
    {
        return l < r.x && l < r.y;
    }
    public static bool operator <(Vector2Int l, int r)
    {
        return l.x < r && l.y < r;
    }
    public static bool operator >(int l, Vector2Int r)
    {
        return l > r.x && l > r.y;
    }
    public static bool operator >(Vector2Int l, int r)
    {
        return l.x > r && l.y > r;
    }

    public static bool operator <=(int l, Vector2Int r)
    {
        return l <= r.x && l <= r.y;
    }
    public static bool operator <=(Vector2Int l, int r)
    {
        return l.x <= r && l.y <= r;
    }
    public static bool operator >=(int l, Vector2Int r)
    {
        return l >= r.x && l >= r.y;
    }
    public static bool operator >=(Vector2Int l, int r)
    {
        return l.x >= r && l.y >= r;
    }



    public static bool operator <(Vector2Int l, Vector2Int r)
    {
        return l.x < r.x && l.y < r.y;
    }
    public static bool operator >(Vector2Int l, Vector2Int r)
    {
        return l.x > r.x && l.y > r.y;
    }

    public static bool operator <=(Vector2Int l, Vector2Int r)
    {
        return l.x <= r.x && l.y <= r.y;
    }
    public static bool operator >=(Vector2Int l, Vector2Int r)
    {
        return l.x >= r.x && l.y >= r.y;
    }


    public static implicit operator Vector2(Vector2Int v)
    {
        return new Vector2(v.x,v.y);
    }
    public static implicit operator Vector2Int(Vector2 v)
    {
        return new Vector2Int(v.x, v.y);
    }


    static Vector2Int zero = new Vector2Int(0, 0);
    public static Vector2Int Zero
    {
        get { return zero; }
    }
    static Vector2Int ANegative = new Vector2Int(-1, -1);
    public static Vector2Int aNegative
    {
        get { return ANegative; }
    }
}